package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.factory.StrategyFactory;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.user.strategy.ItemTypeStrategy;
import com.atguigu.tingshu.user.strategy.impl.AlbumStrategy;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RabbitService rabbitService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;

	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;

	@Autowired
	private TrackInfoFeignClient trackInfoFeignClient;

	@Autowired
	private VipServiceConfigMapper vipServiceConfigMapper;

	@Autowired
	private UserVipServiceMapper userVipServiceMapper;

	@Autowired
	private ItemTypeStrategy itemTypeStrategy;

	@Autowired
	private StrategyFactory strategyFactory;

	@Override
	public void updateVipExpireStatus() {
		userInfoMapper.updateVipExpireStatus();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int savePaidRecord(UserPaidRecordVo userPaidRecordVo) {
//		if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(userPaidRecordVo.getItemType())){
//			ItemTypeStrategy itemTypeStrategy = new AlbumStrategy();
//			itemTypeStrategy.savePaidRecord(userPaidRecordVo);
//		}else if(SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(userPaidRecordVo.getItemType())){
//
//		}else {
//		}
//		int result = itemTypeStrategy.savePaidRecord(userPaidRecordVo);

		ItemTypeStrategy itemTypeStrategy = strategyFactory.getStrategy(userPaidRecordVo.getItemType());
		return itemTypeStrategy.savePaidRecord(userPaidRecordVo);

//		return result;
//		int result = 0;
//		if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(userPaidRecordVo.getItemType())){
//			UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userPaidRecordVo.getUserId()).eq(UserPaidAlbum::getAlbumId, userPaidRecordVo.getItemIdList().get(0)));
//			if (null!=userPaidAlbum){
//				return result;
//			}
//			userPaidAlbum = new UserPaidAlbum();
//			userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
//			userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
//			userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
//			return result+= userPaidAlbumMapper.insert(userPaidAlbum);
//
//		}else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(userPaidRecordVo.getItemType())){
//			List<Long> itemIdList = userPaidRecordVo.getItemIdList();
//
//			Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(itemIdList.get(0));
//
//			Assert.notNull(trackInfoResult,"查询声音失败");
//			TrackInfo trackInfo = trackInfoResult.getData();
//			Assert.notNull(trackInfo,"查询声音失败");
//
//			List<Long> userPaidTrackList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getUserId, userPaidRecordVo.getUserId()).in(UserPaidTrack::getTrackId, itemIdList)).stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
//			for (Long trackId : itemIdList) {
//				if (userPaidTrackList.contains(trackId)){
//					log.warn("退款:"+trackId);
//				}else {
//					UserPaidTrack userPaidTrack = new UserPaidTrack();
//					userPaidTrack.setUserId(userPaidRecordVo.getUserId());
//					userPaidTrack.setTrackId(trackId);
//					userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
//					userPaidTrack.setAlbumId(trackInfo.getAlbumId());
//					result += userPaidTrackMapper.insert(userPaidTrack);
//				}
//			}
//			return result;
//
//		} else {
//			Long vipServiceConfigId = userPaidRecordVo.getItemIdList().get(0);
//			VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(vipServiceConfigId);
//			Integer serviceMonth = vipServiceConfig.getServiceMonth();
//			UserVipService userVipService = new UserVipService();
//
//			UserInfo userInfo = userInfoMapper.selectById(userPaidRecordVo.getUserId());
////			Date vipExpireTime = new Date();
//
//			if (1==userInfo.getIsVip() && userInfo.getVipExpireTime().after(new Date())){
////				Date vipExpireTime = userInfo.getVipExpireTime();
////				LocalDateTime localDateTime = new LocalDateTime(vipExpireTime);
////				localDateTime.plusMonths(serviceMonth);
////				userVipService.setExpireTime(localDateTime.toDate());
//
//				LocalDateTime localDateTime = userInfo.getVipExpireTime().toInstant()
//						.atZone(ZoneId.systemDefault())
//						.toLocalDateTime().plusMonths(serviceMonth);
////				localDateTime = localDateTime.plusMonths(serviceMonth);
//				userVipService.setExpireTime(Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()));
//			}else {
//				LocalDateTime now = LocalDateTime.now();
//				LocalDateTime expireTime = now.plusMonths(serviceMonth);
//				userVipService.setExpireTime(Date.from(expireTime.atZone(ZoneId.systemDefault()).toInstant()));
//			}
//
//			userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
//			userVipService.setUserId(userPaidRecordVo.getUserId());
//			userVipService.setStartTime(new Date());
//
//
//			result += userVipServiceMapper.insert(userVipService);
//
//			userInfo.setIsVip(1);
//			userInfo.setVipExpireTime(userVipService.getExpireTime());
//			result += userInfoMapper.updateById(userInfo);
//
//		}
//
	}

	@Override
	public List<Long> findUserPaidTrackList(Long albumId, Long userId) {

		return userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().
				eq(UserPaidTrack::getAlbumId,albumId).eq(UserPaidTrack::getUserId,userId)).
				stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
	}

	@Override
	public Map<String, Object> wxLogin(String code) {
		//声明一个Map集合
		HashMap<String, Object> map = new HashMap<>();
		//容器自己构建的对象缺少：appid secret
		WxMaJscode2SessionResult wxMaJscode2SessionResult = null;
		try {
			wxMaJscode2SessionResult = wxMaService.jsCode2SessionInfo(code);
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}
		//获取到了微信用户对应的微信标识
		String openid = wxMaJscode2SessionResult.getOpenid();
		//通过这个openid查询用户信息，如果有对应的消息记录，则说明用户已经注册过，如果没有，说明用户未注册，实现注册功能，并初始化账户金额，留住用户
		UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid));
		//判断用户信息是否存在
		if (null == userInfo){
			//第一次注册
			//发送消息实现初始化账户信息
			userInfo = new UserInfo();
			userInfo.setWxOpenId(openid);
			userInfo.setNickname("用户"+ UUID.randomUUID().toString().replaceAll("-",""));
			userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
			//添加到表中
			userInfoMapper.insert(userInfo);
			//发送一个信息，并返回一个token
			rabbitService.sendMessage(MqConst.EXCHANGE_USER,MqConst.ROUTING_USER_REGISTER,userInfo.getId());
		}
		//直接存储到缓存，并返回一个token
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		//缓存key
		String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		redisTemplate.opsForValue().set(userLoginKey,userInfo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
		//存储数据
		map.put("token",token);
		//返回数据
		return map;

	}

	@Override
	public UserInfoVo getUserInfo(Long userId) {
		//查询数据
		UserInfo userInfo = this.getById(userId);
		//属性拷贝
		UserInfoVo userInfoVo = new UserInfoVo();
		BeanUtils.copyProperties(userInfo,userInfoVo);
		//返回数据
		return userInfoVo;
	}

	@Override
	public void updateUserInfo(UserInfoVo userInfoVo, Long userId) {
		//创建对象
		UserInfo userInfo = new UserInfo();
		//属性拷贝
		BeanUtils.copyProperties(userInfoVo,userInfo);
		userInfo.setId(userId);
		//更新用户信息
		userInfoMapper.updateById(userInfo);

	}

	@Override
	public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackNeedPaidList, Long userId) {

		// 创建一个HashMap来存储音轨ID和其对应的支付状态
		HashMap<Long, Integer> map = new HashMap<>();
		
		// 查询用户是否已支付专辑
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().
		        eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
		
		// 如果用户已支付专辑，所有音轨均需付费
		if (null != userPaidAlbum){
		    // 将所有需要付费的音轨ID映射为键，值设为1表示已付费
		    return trackNeedPaidList.stream().collect(Collectors.toMap(trackId->trackId,trackId->1));
		} else {
		    // 创建查询条件，用于查询用户已支付的音轨
		    LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
		    wrapper.eq(UserPaidTrack::getUserId, userId)
		            .in(UserPaidTrack::getTrackId, trackNeedPaidList)
		            .eq(UserPaidTrack::getAlbumId, albumId);
		    
		    // 获取用户已支付的音轨ID列表
		    List<Long> userPaidTrackIdList = userPaidTrackMapper.selectList(wrapper).stream()
		            .map(UserPaidTrack::getTrackId).collect(Collectors.toList());
		
		    // 遍历所有需要付费的音轨ID，根据用户是否已支付，设置支付状态
		    for (Long trackId : trackNeedPaidList) {
		        if (userPaidTrackIdList.contains(trackId)){
		            map.put(trackId, 1); // 已支付
		        } else {
		            map.put(trackId, 0); // 未支付
		        }
		    }
		}
		
		// 返回音轨ID和支付状态的映射
		return map;
	}

	@Override
	public Boolean isPaidAlbum(Long albumId, Long userId) {

		System.out.println("album:\t"+userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId)));

		return null != userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId,userId).eq(UserPaidAlbum::getAlbumId,albumId));
	}
}
